package org.andlisp.awt;

import jp.tyas.libs.terminal.*;
import jp.tyas.libs.lisp.Toplevel;

import java.awt.Frame;
import java.awt.Component;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.util.Vector;
import java.util.Hashtable;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.IOException;

public class AwtTerminal extends Component implements Terminal, KeyListener, TerminalBuffer.TextUpdatedListener
{
  BaseTerminal term;
  BaseTerminal.Connection con;

  public AwtTerminal () {
    Hashtable props = new Hashtable();
    props.put ("color.background", Color.black);
    props.put ("color.text", Color.white);
    props.put ("offset.x", Integer.valueOf(10));
    props.put ("offset.y", Integer.valueOf(10));
    props.put ("font", new Font (null, Font.PLAIN, 12));
    term = new BaseTerminal(0, props);
    term.setTextUpdatedListener(this);

    addKeyListener(this);
    setFocusable(true);
    setVisible(true);
  }

  public void keyPressed(KeyEvent e) {}
  public void keyReleased(KeyEvent e) {}

  public void keyTyped(KeyEvent e) {
    term.putCharIn(e.getKeyChar());
  }

  public void textUpdated() {
    repaint();
  }

  public Terminal.Connection openConnection() {
    con = (BaseTerminal.Connection)term.openConnection();
    return con;
  }

  public void paint (Graphics g) {
    g.setColor ((Color)con.getProperty ("color.background"));
    g.fillRect (0, 0, getWidth(), getHeight());
    g.setColor ((Color)con.getProperty ("color.text"));
    g.setFont ((Font)con.getProperty ("font"));

    int xofs = ((Integer)con.getProperty ("offset.x")).intValue();
    int yofs = ((Integer)con.getProperty ("offset.y")).intValue();
    int txh = g.getFontMetrics().getHeight() - 2;
    int siz = term.size();
    int max = (getHeight() - yofs) / txh - 2;
    int sta = siz - max;
    int min = max < siz ? max: siz;
    int i;

    if (sta < 0) sta = 0;

    for (i = 0; i < min-1; i++)
      g.drawString (term.getLine(sta + i), xofs, yofs + i*txh);
    g.drawString (term.getLine(sta + i) + "<", xofs, yofs + i*txh);
  }

  public static void main (String[] args) {
    Frame f = new Frame();
    Terminal term = new AwtTerminal();
        
    f.add((Component)term);
    f.setSize(800, 600);
    f.show();

    Terminal.Connection con = term.openConnection();
    Toplevel lisp = new Toplevel
      (new InputStreamReader(con.getInputStream()),
       new PrintStream(con.getOutputStream()));
    
    lisp.repl ();
  }
}
